/*
 * @Author: czy
 * @Date: 2021-04-04 22:39:40
 * @LastEditTime: 2021-04-10 15:25:27
 */
#define BUFSIZE 400
#define va_start(v, l) __builtin_va_start(v, l)
#define va_end(v) __builtin_va_end(v)
#define va_arg(v, l) __builtin_va_arg(v, l)
typedef __builtin_va_list va_list;

extern void append2screen(char *str, int color);
extern void uart_put_chars(char *str);
extern void strzero(char *str, int len);
extern int vsprintf(char *buf, const char *fmt, va_list args);
extern int sprintf(char *buf, const char *fmt, ...);

/**
 * @description: Formats a string in the specified format, and output on VGA and serial port.
 * @param buf   The first address of the buffer.
 * @param fmt   Format string.
 * @param args  Parameter list.
 * @return The length of the string in the buffer.
 */
int myPrint(char *buf, int color, const char *format, va_list args)
{
    int n;
    strzero(buf, BUFSIZE);
    n = vsprintf(buf, format, args);
    append2screen(buf, color);
    uart_put_chars(buf);
    return n;
}

// Kernel version.
char kBuf[BUFSIZE];
int myPrintk(int color, const char *format, ...)
{
    int n;
    va_list args;
    va_start(args, format);
    n = myPrint(kBuf, color, format, args);
    va_end(args);
    return n;
}

// User version.
char uBuf[BUFSIZE];
int myPrintf(int color, const char *format, ...)
{
    int n;
    va_list args;
    va_start(args, format);
    n = myPrint(uBuf, color, format, args);
    va_end(args);
    return n;
}